#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "LPC23xx.H"
#include "bas_fun.h"
#include "uart_fun.h" 
#include "lcd_fun.h"
#include "aio_fun.h"

#ifdef WEB_CAM_FUN
#include "webcam.h"
#endif
#ifdef AEC_FUN
#include "aec_fun.h"
#endif

#define _ctns "\x8e\x85\x94\x83\x8f\x8e\xda\x97"
void ctns_fun(void) { Pprintf(-1,"%s",_ctns); }
void timer0_aio_pro(void);
void DoNetworkStuff(void);
void int_timer0 (void) __irq 
{  
	   tick_rdy++;
	   
	   real_ms();
	   
#ifdef LCD_FUN	   
	   if (!ioport_stop) lcd_key=~LCD_KEY_IN();
#endif
	   
#ifdef WDOG	
       if (WDogCount<5000) {  // 5000ms
	      WDogCount++;
		  WDFEED = 0xAA;
	      WDFEED = 0X55; 
	   }
#endif
       

#ifdef FLASH_FUN
       if (WFLASH_flag) {
	       switch(WFLASH_flag) {
#ifdef WFLASH_FLAG_EW
		      case WFLASH_FLAG_EW :
	              WFLASH_ret=wflash_write(WFLASH_addr,WFLASH_buf,WFLASH_wsize); 
				  break;
#endif
#ifdef WFLASH_FLAG_PEW
			  case WFLASH_FLAG_PEW :
	              WFLASH_ret=wflash_page_write(WFLASH_addr,WFLASH_buf,WFLASH_wsize); 
				  break;
#endif				  
#ifdef WFLASH_FLAG_E
			  case WFLASH_FLAG_E   :
	              WFLASH_ret=wflash_erase(WFLASH_addr); 
				  break;
#endif
		   }
		   WFLASH_flag=0;
	   }
#endif  // FLASH_FUN	   


#ifdef I2C_NUM
       if (I2C_flag) {
	       switch(I2C_flag) {
		      case I2C_FLAG_READ :
	              I2C_read_pro(I2C_addr,I2C_buf,I2C_dsize); 
				  break;
			  case I2C_FLAG_WRITE :
	              I2C_write_pro(I2C_addr,I2C_buf,I2C_dsize); 
				  break;
		   }
		   I2C_flag=0;
	   }
#endif      
	 	 

#ifdef CRC16
       if (CRC2_flag) {
           CRC2_rcrc=get_crc2(CRC2_rcrc,(unsigned char *)CRC2_s,CRC2_slen);
	       CRC2_flag=0;
	   }
#endif
       
       timer0_aio_pro();

       T0IR = 1;                                 // Clear Interrupt Flag 
       VICVectAddr = 0;                          // Acknowledge Interrupt 
}


#define Timer_1s    CPU_HZ/1 - 1
#define Timer_100ms CPU_HZ/10 - 1
#define Timer_10ms  CPU_HZ/100 - 1
#define Timer_1ms   CPU_HZ/1000 - 1
#define Timer_100ws CPU_HZ/10000 - 1
#define Timer_10ws  CPU_HZ/100000 - 1
#define Timer_1ws   CPU_HZ/1000000 - 1

void init_timer0(void) {

    PCONP   |= (1<<1);
    // Setup Timer Counter 0: Periodic Timer with Interrupt at DATA_FREQ Rate */
	T0MR0 = Timer_1ms;
    T0MCR = 3;                  // TCO Interrupt and Reset on MR0 
    T0TCR = 1;                  // TC0 Enable 

    // Setup Timer Counter 0 Interrupt 
    VICVectAddr4 = (unsigned long)int_timer0;    // TC0 Interrupt -> Vector 4   
    VICVectCntl4 = 4;                            // TC0 Interrupt -> Priority 2 
    VICIntEnable |= (1 << 4);                    // Enable TC0 Interrupt 
	tick_rdy=0;
	Tms=0;	
}

////////////////////////////////////////////////////

void int_timer1 (void) __irq 
{
 
#ifdef WEB_CAM_FUN
     usb_int_pro();  EX0_USE_P0;  EX1_USE_P0; 
#endif
	
#ifdef LCD_OUT_INT
     if (lcd_out_flag) {
	    if (!ioport_stop) {
	       if (lcd_out_flag==1) { LCD_RS(1); LCD_RW(0); LCD_DATA_OUT(lcd_out_c); }
		   else if (lcd_out_flag==2) { LCD_RS(0); LCD_RW(0); LCD_DATA_OUT(lcd_out_c); }
		}
		lcd_out_flag=0;
	 }
#endif	 

#ifdef CDO_INT_PRO
     if (cdo_in_flag)  {  DOH_IN();  cdo_in_flag=0;  }
	 if (cdo_out_flag) {  DOH_OUT(doh_out_c,DOH_STUS[doh_out_c]); cdo_out_flag=0; }
#endif	  

     if (net_rdy) { if (MAC_RXPRODUCEINDEX != MAC_RXCONSUMEINDEX)  DoNetworkStuff(); }
	 
     T1IR = 1;                                 /* Clear Interrupt Flag */
     VICVectAddr = 0;                          /* Acknowledge Interrupt */
}

void init_timer1(void) 
{

  PCONP   |= 0x00000004;
  /* Setup Timer Counter 1: Periodic Timer with Interrupt at DATA_FREQ Rate */
  T1MR0 = Timer_100ws;
  T1MCR = 3;                                /* TC1 Interrupt and Reset on MR0 */
  T1TCR = 1;                                /* TC1 Enable */

  VICVectAddr5  = (unsigned long)int_timer1; /* TC1 Interrupt -> Vector    */
  VICVectCntl5  =  5;                         /* TC1 Interrupt -> Priority  */
  VICIntEnable |= 1 << 5;                   /* Enable TC1 Interrupt */
}


/////////////////////////////////////////////////////////////////
#ifdef AEC_FUN
int enc_dly,o_Height_mm;
unsigned int enc_h;
int encoder_H;
void  encoder_rst(void)
{
	encoder_H=0;
    UPD_RST(1);  UPD_RST(0); 
	encoder_H=0;
	encoder_val=0;
	NowHeight=0;
	enc_h=0;
	enc_dly=0; 
	o_Height_mm=0;
	
}

int  ERRC_p4_p6(void);
void ERRC_p16(int stus);

int Level1_Hmm,LevelData_o;
void  encoder_input(int dly)
{
    int Height_mm,move_mm,cbit,ch;
	int flrHeight,m;
	
	Level_stus = ((~DIH1_IN)>>5)&0x7;
	ErrSysStus=inport(0x0A)&0xff;	
	encoder_val=inport(0x06)+(encoder_H*256);
	Height_mm=(int)(encoder_val*paec->base.EncoderFactor*10);
	NowHeight=Height_mm/10;
	enc_dly+=dly;
	if (enc_dly>=ENCODER_BUFF_TICK) {
	    enc_dly=0;
		move_mm=abs(Height_mm-o_Height_mm);
	    EncoderSpeed=(int)(move_mm*(1000/ENCODER_BUFF_TICK)/10);
		if (enc_h>=ENCODER_BUFF_NUM) enc_h=0;
		ENC[enc_h].EncoderSpeed	= EncoderSpeed;
		ENC[enc_h].LevelData = Level_stus;
		enc_h++;
		o_Height_mm=Height_mm;
		if (move_mm>=2) cbit=1; else cbit=0;
		ch=DO_INV_MOVE;		
	    if (Ibit(DOH_STUS,ch)!=cbit) {
		    Isetbit(DOH_STUS,ch,cbit);
			DOH_OUT(ch/8,DOH_STUS[ch/8]);
	    }
    }
	if (LevelData_o!=Level_stus) {
	   if (LevelData_o==0x0) {
	      if ((Level_stus==0x1)||(Level_stus==0x4)) Level1_Hmm=Height_mm;  
		  else Level1_Hmm=0;
	   }	   
	   else if (Level_stus==0x7) {
		  Level3_dist_mm=abs(Level1_Hmm-Height_mm);			  
	      if ((pflrs->dest_floor>=0)&&(pflrs->now_floor>=0)&&(paec->dist.DistMaxErr>0)) {
			  flrHeight=paec->base.FlrHeight[pflrs->now_floor];
		      last_level_m=m=abs(NowHeight-flrHeight);
		      if (m<3) ;   // 3 cm
			  else {
			     if (m>paec->dist.DistMaxErr) ERRC_p16(1);  // > 35 cm
			     encoder_H=((int)(flrHeight/paec->base.EncoderFactor))/256;
			  }
		  }
	   }	   
	   LevelData_o=Level_stus;
	}
}
  
void int_extint3(void) __irq 
{

  if (IO0_INT_STAT_F&(1<<6)) {
     encoder_H++;
     IO0_INT_CLR|=1<<6;
  }

  if (IO0_INT_STAT_F&(1<<7)) {
     encoder_H--;
     IO0_INT_CLR|=1<<7;
  }

  //EXTINT |= 0x08;

  VICVectAddr = 0;                          /* Acknowledge Interrupt */
}


void init_extint3(void) 
{

  IO0_INT_EN_F|=(1<<6);	                      //Interrupt P0.6 falling edge
  IO0_INT_EN_F|=(1<<7);	         			  //Interrupt P0.7 falling edge

  /* Setup Ext-Int3 Interrupt */
  VICVectAddr17 = (U32)int_extint3;           /* Ext-Int3 Interrupt -> Vector 17   */
  VICVectCntl17 = 17;                         /* Ext-Int3 Interrupt -> Priority 10 */
  VICIntEnable |= 1 << 17;                    /* Enable Ext-Int3 Interrupt */
}
#endif
